package models

import (
	"context"
	"fmt"
	"time"

	"go-papers/cache"
	orm "go-papers/database"
	"go-papers/pkg/lognew"
	"go-papers/tools"
)

type Organ struct {
	OrganId int `json:"organId" gorm:"type:int(11) unsigned;primary_key"` //

	OrganBrand   string `json:"organBrand" gorm:"type:varchar(255);"`  // 品牌名称 --
	OrganBrandId int    `json:"organBrandId" gorm:"type:int(11);"`     // 品牌名称 --
	OrganName    string `json:"organName" gorm:"type:varchar(255);"`   // 机构名称 --
	OrganCapital string `json:"organCapital" gorm:"type:varchar(32);"` // 注册资金 --

	OrganImage string `json:"organImage" gorm:"type:text;"` // 机构图 --

	OrganProvince string `json:"organProvince" gorm:"type:varchar(255);"` // 机构省份 --
	OrganCity     string `json:"organCity" gorm:"type:varchar(255);"`     // 城市    --
	OrganArea     string `json:"organArea" gorm:"type:varchar(255);"`     // 区域    --
	OrganAddr     string `json:"organAddr" gorm:"type:varchar(255);"`     // 机构详细地址 --
	OrganAddrTxt  string `json:"organAddrTxt" gorm:"type:text;"`          // 地址json数据  --

	//organRegister）
	OrganAchievement string `json:"organAchievement" gorm:"type:text;"` // 优秀历史业绩字段

	OrganLt string `json:"organLt" gorm:"type:varchar(64);"` // 经纬度   -- 经度
	OrganWt string `json:"organWt" gorm:"type:varchar(64);"` // 经纬度   -- 纬度

	OrganMoneyType string  `json:"organMoneyType" gorm:"type:varchar(64);"` // 机构佣金类型 1 佣金金额  2 佣金比例
	OrganRate      float64 `json:"organRate" gorm:"type:decimal(10,2);"`    // 用户比例
	OrganMoney     string  `json:"organMoney" gorm:"type:varchar(64);"`     // 佣金金额

	OrganPayType    string `json:"organPayType" gorm:"type:varchar(255);"`    // 机构支付账户类型
	OrganPayAccount string `json:"organPayAccount" gorm:"type:varchar(255);"` // 支付账户 商户号

	OrganTel             string `json:"organTel" gorm:"type:varchar(255);"`             // 机构联系电话
	OrganFeature         string `json:"organFeature" gorm:"type:text;"`                 // 机构特点 -- json 数组： 1  线上， 2  线下 3 优惠
	OrganBusiness        string `json:"organBusiness" gorm:"type:varchar(32);"`         // 经营方式：1 直营 、 2 加盟
	OrganBusinessLicense string `json:"organBusinessLicense" gorm:"type:varchar(255);"` // 营业执照
	OrganPayOnline       string `json:"organPayOnline" gorm:"type:varchar(255);"`       // 经营合同是否在线支付 1 是 ， 0 不是

	OrganBusinessTxt  string `json:"organBusinessTxt" gorm:"type:text;"`  // 经营方式合同（经营方式的证明材料）
	OrganPayOnlineTxt string `json:"organPayOnlineTxt" gorm:"type:text;"` // 在线支付合同（在线支付的证明材料）
	OrganFeatureTxt   string `json:"organFeatureTxt" gorm:"type:text;"`   // 机构特点 文本信息

	OrganCourseNums  int `json:"organCourseNums" gorm:"type:int(10);"`  // 课程科目数量
	OrganCourseOrder int `json:"organCourseOrder" gorm:"type:int(10);"` // 平台总销量
	OrganTeacherNums int `json:"organTeacherNums" gorm:"type:int(10);"` // 教师数量
	OrganTeacherAge  int `json:"organTeacherAge" gorm:"type:int(3);"`   // 平均年龄

	OrganTeacherFlow string `json:"organTeacherFlow" gorm:"type:varchar(255);"` // 教师流动性

	OrganRegister   string `json:"organRegister" gorm:"type:varchar(32);"`    // 机构成立时间
	OrganCover      string `json:"organCover" gorm:"type:varchar(255);"`      // 机构封面图
	OrganQualify    string `json:"organQualify" gorm:"type:varchar(255);"`    // 办学资质
	OrganEnv        string `json:"organEnv" gorm:"type:varchar(255);"`        // 环境安全
	OrganPay        string `json:"organPay" gorm:"type:varchar(255);"`        // 在线支付
	OrganCourseType string `json:"organCourseType" gorm:"type:varchar(255);"` // 机构下 课程类别
	OrganFinancing  string `json:"organFinancing" gorm:"type:text;"`          // 融资情况 改为图片

	OrganCourseQualify  string `json:"organCourseQualify" gorm:"type:varchar(255);"`  // 研发能力材料 图片
	OrganTeacherQualify string `json:"organTeacherQualify" gorm:"type:varchar(255);"` // 教师体系材料 图片
	OrganFina           string `json:"organFina" gorm:"type:varchar(255);"`           // 财务授权 图片
	OrganBrandLogo      string `json:"organBrandLogo" gorm:"type:varchar(255);"`      // 品牌logo 图片

	OrganUserId int    `json:"organUserId" gorm:"type:int(11);"` // 机构用户id
	OrganDesc   string `json:"organDesc" gorm:"type:text;"`      // 机构简介

	OrganTeacherTxt string `json:"organTeacherTxt" gorm:"type:text;"` // 机构教师平均年龄证明材料

	OrganMomId   int    `json:"organMomId" gorm:"type:int(11);"`        // 机构引导的 社区达人
	OrganMomName string `json:"organMomName" gorm:"type:varchar(255);"` // 机构引导的 社区达人 姓名

	OrganHots string `json:"organHots" gorm:"type:varchar(32);"` // 机构热度

	CreateBy         string `json:"createBy" gorm:"type:varchar(255);"`        // 创建人
	UpdateBy         string `json:"updateBy" gorm:"type:varchar(255);"`        // 更新人
	CreateByName     string `json:"createByName" gorm:"type:varchar(255);"`    // 创建人
	UpdateByName     string `json:"updateByName" gorm:"type:varchar(255);"`    // 更新人
	ApprovalStatus   string `json:"approvalStatus" gorm:"type:varchar(32);"`   // 核准状态
	ApprovalAt       string `json:"approvalAt" gorm:"type:varchar(32);"`       // 核准时间
	ApprovalUserId   string `json:"approvalUserId" gorm:"type:varchar(32);"`   // 核准人id
	ApprovalUserName string `json:"approvalUserName" gorm:"type:varchar(32);"` // 核准人名称

	OrganExtra string `json:"organExtra" gorm:"type:text;"` // 额外扩展字段

	UpdateStart string `json:"updateStart" gorm:"-"`              // 跟新 起始时间
	UpdateEnd   string `json:"updateEnd" gorm:"-"`                // 跟新 结束时间
	MomTel      string `json:"momTel" gorm:"type:varchar(255);"`  //电话
	MomCode     string `json:"momCode" gorm:"type:varchar(255);"` //电话
	LocationKm  string `json:"locationKm" gorm:"-"`               // 距离

	DataScope string `json:"dataScope" gorm:"-"`
	Params    string `json:"params"  gorm:"-"`
	BaseModel
}

func (Organ) TableName() string {
	return "organ"
}

type SearchReq struct {
	OrganBrandId   int    `json:"organBrandId" ` // 机构名称 --
	OrganName      string `json:"organName" `    // 机构名称 --
	OrganBrand     string `json:"organBrand" `   // 品牌名称 --
	OrganAddr      string `json:"organAddr" `    // 机构详细地址 --
	OrganFeature   string `json:"organFeature" ` // 机构特点 -- json 数组： 1  线上， 2  线下 3 优惠
	OrganDesc      string `json:"organDesc" `    // 机构简介 教育类别搜索
	MemberId       int    `json:"memberId" `
	OpenId         string `json:"openId" `
	KeyWord        string `json:"keyword" `
	CourseType     string `json:"courseType" `
	LocationKm     string `json:"locationKm" `     // 距离搜索
	LocationKmType string `json:"locationKmType" ` // 距离搜索

}

// 创建Organ
func (e *Organ) Create() (Organ, error) {
	var doc Organ
	result := orm.Eloquent.Table(e.TableName()).Create(&e)
	if result.Error != nil {
		err := result.Error
		return doc, err
	}
	doc = *e
	return doc, nil
}

// 获取Organ
func (e *Organ) GetByID(id int) (Organ, error) {
	var doc Organ

	//cache 读取 然后返回
	cacheKey := fmt.Sprintf("organ:%d", id)
	if foo, ok := cache.GoLocalCache.Get(cacheKey); ok {
		l, _ := foo.(Organ)
		return l, nil
	}

	table := orm.Eloquent.Table(e.TableName())
	table = table.Where("organ_id = ?", id)
	if err := table.First(&doc).Error; err != nil {
		return doc, err
	}

	// 写入cache
	cache.GoLocalCache.Set(cacheKey, doc, 5*time.Minute)

	return doc, nil
}

func (e *Organ) GetCountByMom(oid int) int {
	var count int
	table := orm.Eloquent.Table(e.TableName())
	table = table.Where(" organ_mom_id = ?", oid)
	table.Where("`deleted_at` IS NULL").Count(&count)
	return count
}

// 获取Organ
func (e *Organ) Get() (Organ, error) {
	var doc Organ
	table := orm.Eloquent.Table(e.TableName()).Select("`organ`.* , `member`.phone as mom_tel , `member`.member_code as mom_code")
	table = table.Joins("left join `member` ON `member`.member_id = `organ`.organ_mom_id ")
	if e.OrganId != 0 {
		table = table.Where(" `organ`.organ_id = ?", e.OrganId)
	}
	if e.OrganBrand != "" {
		table = table.Where("organ.organ_brand like ?", "%"+e.OrganBrand+"%")
	}
	if e.OrganName != "" {
		table = table.Where("organ.organ_name like ?", "%"+e.OrganName+"%")
	}
	if e.OrganMomId != 0 {
		table = table.Where("organ.organ_mom_id = ?", e.OrganMomId)
	}
	if e.CreateBy != "" {
		table = table.Where("organ.create_by = ?", e.CreateBy)
	}
	if e.ApprovalStatus != "" {
		table = table.Where("organ.approval_status = ?", e.ApprovalStatus)
	}
	if e.ApprovalUserName != "" {
		table = table.Where("organ.approval_user_name like ?", "%"+e.ApprovalUserName+"%")
	}
	table = table.First(&doc)
	if err := table.Error; err != nil {
		return doc, err
	}
	return doc, nil
}

type OrganList struct {
	OrganId    int    `json:"organId" gorm:"type:int(11) unsigned;primary_key"` //
	OrganBrand string `json:"organBrand" gorm:"type:varchar(255);"`             // 品牌名称 --
	OrganName  string `json:"organName" gorm:"type:varchar(255);"`              // 机构名称 --
}

// GetList
func (e *Organ) GetList(uid int, userType, selectType string) ([]OrganList, error) {
	var doc []OrganList
	table := orm.Eloquent.Select("organ_id,organ_name,organ_brand").Table(e.TableName())
	if selectType == "1" {
		table = table.Where("organ_id = ?", "1")
	} else if selectType == "2" {
		table = table.Where("organ_id = ?", "2")
	} else if selectType == "3" {
		// 当前用户所在机构
		if userType == "3" {
			// 获取用户部门 deptId 及部门下的机构id list
			var user SysUser
			ids, _ := user.GetById(uid)
			table = table.Where("organ_id = ?", ids.OrganId)
		} else {
			table = table.Where(" organ_id >= 3 ")
		}

	}

	if err := table.Order("`updated_at` DESC", true).Find(&doc).Error; err != nil {
		return nil, err
	}
	return doc, nil
}

func (e *Organ) GetOrganIdByUid(uid int, isNew bool) []int {
	var doc []int

	//cache 读取 然后返回
	cacheKey := fmt.Sprintf("organ:uid:%d", uid)

	//cache
	if isNew {
		if foo, ok := cache.GoLocalCache.Get(cacheKey); ok {
			l, _ := foo.([]int)
			return l
		}
	}

	var docList []Organ
	table := orm.Eloquent.Select("organ_id,organ_name,organ_brand").Table(e.TableName())
	table = table.Where(" organ_mom_id = ?", uid)
	if err := table.Order("`updated_at` DESC", true).Find(&docList).Error; err != nil {
		doc = append(doc, -1)
	}
	if len(docList) > 0 {
		for _, v := range docList {
			doc = append(doc, v.OrganId)
		}
	} else {
		doc = append(doc, -1)
	}

	// 设置cache
	cache.GoLocalCache.Set(cacheKey, doc, 5*time.Minute)

	return doc
}

type OrganPPList struct {
	OrganId   int    `json:"organId" gorm:"type:int(11);"`        //
	OrganName string `json:"organName" gorm:"type:varchar(255);"` // 机构名称 --
	Distance  string `json:"distance" gorm:"type:varchar(255);"`
}

// GetListByPosition
func (e *Organ) GetListByPosition(lt, wt string, end, start float64) ([]OrganPPList, error) {
	var doc []OrganPPList
	table := orm.Eloquent.Table(e.TableName())
	lat := lt
	lng := wt
	sql := "organ_id,organ_name,( 6371 * acos ( cos ( radians(" + lat + ") )* cos( radians( organ_lt ) ) * cos( radians( organ_wt ) - radians(" + lng + ") )" +
		" + sin ( radians(" + lat + ") )* sin( radians( organ_lt ) ))) AS distance "

	hh := fmt.Sprintf("distance >= %f AND distance <= %f ", start, end)
	lognew.Info(context.TODO(), "GetListByPosition", lognew.Fields{"sql": sql, "hh": hh, "start": start, "end": end})

	if err := table.Select(sql).Having(hh).Order("distance ASC ", true).Find(&doc).Error; err != nil {
		return nil, err
	}
	return doc, nil
}

// 获取Organ带分页
// gateway
func (e *Organ) GetPageSearch(pageSize int, pageIndex int, ss SearchReq) ([]Organ, int, error) {
	var doc []Organ

	table := orm.Eloquent.Select("*").Table(e.TableName())
	table = table.Where("approval_status = 5")

	if e.OrganMomId != 0 {
		table = table.Where("organ_mom_id = ?", e.OrganMomId)
	}
	if ss.OrganBrand != "" {
		table = table.Where("organ_brand LIKE ?", "%"+ss.OrganBrand+"%")
	}
	if ss.OrganBrandId != 0 {
		table = table.Where("organ_brand_id = ?", ss.OrganBrandId)
	}
	if ss.CourseType != "" {
		table = table.Where("organ_course_type LIKE ?", "%"+ss.CourseType+"%")
	}
	if ss.OrganName != "" {
		table = table.Where("organ_name LIKE ?", "%"+ss.OrganName+"%")
	}
	if ss.OrganAddr != "" {
		table = table.Where("organ_addr LIKE ?", "%"+ss.OrganAddr+"%")
	}
	if ss.OrganFeature != "" {
		table = table.Where("organ_feature LIKE ?", "%"+ss.OrganFeature+"%")
	}
	if ss.OrganDesc != "" {
		table = table.Where("organ_desc LIKE ?", "%"+ss.OrganDesc+"%")
	}
	if ss.KeyWord != "" {
		table = table.Where("organ_name LIKE ? OR  organ_brand LIKE ? ", "%"+ss.KeyWord+"%", "%"+ss.KeyWord+"%")

	}

	start := 0.0
	end := 0.0
	if ss.LocationKmType != "" {
		if ss.LocationKmType == "1" {
			start = 0
			end = 0.5
		}
		if ss.LocationKmType == "2" {
			start = 0.5
			end = 2
		}
		if ss.LocationKmType == "3" {
			start = 2
			end = 5
		}
		if ss.LocationKmType == "4" {
			start = 5
			end = 10000
		}
		//当前用户位置 与 机构 距离 位置
		var pp MemberPosition
		pp.OpenId = ss.OpenId
		pp.MemberId = ss.MemberId
		organIds := pp.GetOrgansArr(end, start)

		if len(organIds) > 0 {
			table = table.Where("organ_id in (?)", organIds)
		} else {
			table = table.Where("organ_id in (-1)")
		}
	}

	var count int

	if err := table.Order("`updated_at` DESC", true).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
		return nil, 0, err
	}
	table.Where("`deleted_at` IS NULL").Count(&count)

	// 处理数据 新增 距离返回
	ll := len(doc)
	if ll > 0 {
		//获取用户当前的位置
		var pp MemberPosition
		pIn, _ := pp.GetByIdOrOpenId(ss.MemberId, ss.OpenId)

		for i := 0; i < ll; i++ {

			nl := doc[i]
			km := tools.GetMemberLocation(pIn.MemberLt, pIn.MemberWt, nl.OrganLt, nl.OrganWt)
			doc[i].LocationKm = km
		}
	}

	return doc, count, nil
}

// 获取Organ带分页
func (e *Organ) GetPage(pageSize int, pageIndex int) ([]Organ, int, error) {
	var doc []Organ

	table := orm.Eloquent.Select("*").Table(e.TableName())
	if e.OrganId != 0 {
		table = table.Where("organ_id = ?", e.OrganId)
	}
	if e.OrganBrand != "" {
		table = table.Where("organ_brand LIKE ?", "%"+e.OrganBrand+"%")
	}
	if e.OrganBrandLogo != "" {
		table = table.Where("organ_brand_logo = ?", e.OrganBrandLogo)
	}
	if e.OrganName != "" {
		table = table.Where("organ_name LIKE ?", "%"+e.OrganName+"%")
	}
	if e.OrganRegister != "" {
		table = table.Where("organ_register = ?", e.OrganRegister)
	}
	if e.OrganTeacherNums != 0 {
		table = table.Where("organ_teacher_nums = ?", e.OrganTeacherNums)
	}
	if e.OrganBusiness != "" {
		table = table.Where("organ_business = ?", e.OrganBusiness)
	}
	if e.OrganProvince != "" {
		table = table.Where("organ_province = ?", e.OrganProvince)
	}
	if e.OrganCity != "" {
		table = table.Where("organ_city = ?", e.OrganCity)
	}
	if e.OrganArea != "" {
		table = table.Where("organ_area = ?", e.OrganArea)
	}
	if e.OrganMomId != 0 {
		table = table.Where("organ_mom_id = ?", e.OrganMomId)
	}
	if e.CreateBy != "" {
		table = table.Where("create_by = ?", e.CreateBy)
	}
	if e.UpdateBy != "" {
		table = table.Where("update_by = ?", e.UpdateBy)
	}
	if e.ApprovalStatus != "" {
		table = table.Where("approval_status = ?", e.ApprovalStatus)
	}
	if e.ApprovalUserName != "" {
		table = table.Where("approval_user_name = ?", e.ApprovalUserName)
	}

	//data.UpdateStart
	if e.UpdateStart != "" {
		table = table.Where("updated_at >= ?", e.UpdateStart)
	}
	if e.UpdateEnd != "" {
		table = table.Where("updated_at <= ?", e.UpdateEnd)
	}

	// 数据权限
	table, _ = HandleOrganCommonTable(table, "organ", e.DataScope, "机构列表") // 分佣金列表

	var count int

	if err := table.Order(" `updated_at` DESC", true).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
		return nil, 0, err
	}

	table.Where("`deleted_at` IS NULL").Count(&count)

	return doc, count, nil
}

// 更新Organ
func (e *Organ) Update(id int) (update Organ, err error) {
	if err = orm.Eloquent.Table(e.TableName()).Where("organ_id = ?", id).First(&update).Error; err != nil {
		return
	}

	//参数1:是要修改的数据
	//参数2:是修改的数据
	if err = orm.Eloquent.Table(e.TableName()).Model(&update).Updates(&e).Error; err != nil {
		return
	}
	return
}

// 删除Organ
func (e *Organ) Delete(id int) (success bool, err error) {
	if err = orm.Eloquent.Table(e.TableName()).Where("organ_id = ?", id).Delete(&Organ{}).Error; err != nil {
		success = false
		return
	}
	success = true
	return
}

//批量删除
func (e *Organ) BatchDelete(id []int) (Result bool, err error) {
	if err = orm.Eloquent.Table(e.TableName()).Where("organ_id in (?)", id).Delete(&Organ{}).Error; err != nil {
		return
	}
	Result = true
	return
}

func (e *Organ) BatchGet(id []int) ([]Organ, error) {
	var doc []Organ
	if err := orm.Eloquent.Table(e.TableName()).Where("organ_id in (?)", id).Find(&doc).Error; err != nil {
		return nil, err
	}
	return doc, nil
}

func (e *Organ) BatchGetBrandName(id []int) (map[int]string, error) {
	var doc []Organ
	if err := orm.Eloquent.Table(e.TableName()).Where("organ_id in (?)", id).Find(&doc).Error; err != nil {
		return nil, err
	}
	organinfo := make(map[int]string, 0)
	if len(doc) > 0 {
		for _, v := range doc {
			organinfo[v.OrganId] = v.OrganBrand
		}
		return organinfo, nil
	}
	return organinfo, nil
}

func (e *Organ) BatchGetBrandNameV2(id []int) (map[int]Organ, error) {
	var doc []Organ
	if err := orm.Eloquent.Table(e.TableName()).Where("organ_id in (?)", id).Find(&doc).Error; err != nil {
		return nil, err
	}
	organinfo := make(map[int]Organ, 0)
	if len(doc) > 0 {
		for _, v := range doc {
			organinfo[v.OrganId] = v
		}
		return organinfo, nil
	}
	return organinfo, nil
}
